
#include <libfmail.h>
#include <odkutils.h>
#include <libfmail/socketipc.h>

int Server_onRun;

class InternalHandler : public ProtocolHandler{
public:
    int Handle(Socket *s){
        IPC *ipc;
        IPCMessage *msg;
        int onRun;
        
        onRun = 1;
        ipc = new SocketIPC(s);
        
        while(onRun){
            if (ipc->PeekMessage()){
                msg = ipc->PopMessage();
                
                if (!strcmp(msg->GetMessageName(), "shutdown")){
                    Server_onRun = 0;
                    onRun =  0;
                }
                
                delete msg;
            }
        }
        
        return 0;
    }
};

class FSAuth : public ProtocolHandler{
public:
    int Handle(Socket *s){
        IPCMessage *msg;
        IPC *ipc;
        int onRun;
        char *user, *pass, buffer[255], auxbuffer[255];
        FILE *fd;
        
        printf("Got Client\n");
        printf("Creating new IPC\n");
        
        ipc = new SocketIPC(s);
        onRun = 1;
        
        while(onRun){
            printf("Waiting for Message\n");
            if (ipc->PeekMessage()){
                printf("Got Message\n");
                msg = ipc->PopMessage();
                
                if (!strcmp(msg->GetMessageName(), "auth")){
                    printf("Got Auth Request\n");
                    user = msg->PopParam();
                    pass = msg->PopParam();
                    
                    delete msg;
                    printf("Authenticating %s : %s\n", user, pass);
                    
                    sprintf(buffer, "/tmp/fmail/%s.passwd", user);
                    fd = fopen(buffer, "r");
                    if (fd == NULL){
                        msg = new IPCMessage("failed");
                    }else{
                        memset(auxbuffer, 0, 255);
                        fread(auxbuffer, 1, 255, fd);
                        fclose(fd);
                        if (!strcmp(pass, auxbuffer)){
                            msg = new IPCMessage("failed");
                        }else{
                            msg = new IPCMessage("authok");
                        }
                    }
                    ipc->PushMessage(msg);
                    free(user);
                    free(pass);
                    onRun = 0;
                }
            }
        }
        ipc->CloseIPC();
        delete ipc;
        return 0;
    }
};

class SimpleLoad : public LoadHandler{
public:
    int Dispatch(Socket *sock, ProtocolHandler *ph){
        printf("SimpleLoad: Dispatching\n");
        if (ph)
            return ph->Handle(sock);
        return 0;
    }
};

int main(int argc, char **argv){
    BaseServer *serv, *serv_conf;
    LoadHandler *lh;
    FSAuth *fsauth;
    InternalHandler *ih;
    
    printf("Creating new FSAuth\n");
    fsauth = new FSAuth();
    ih = new InternalHandler();
    
    printf("Creating new SimpleLoad\n");
    lh = new SimpleLoad();
    
    printf("Creating new BaseServer\n");
    serv = new BaseServer(fsauth, 14000);
    serv_conf = new BaseServer(ih, 13000);
    
    printf("Setting Load Handler\n");
    serv->SetLoadhandler(lh);
    serv_conf->SetLoadhandler(lh);
    
    printf("Listening\n");
    serv->Listen();
    Server_onRun = 1;
    
    while(Server_onRun){
        serv->Accept();
        serv_conf->Accept();
        printf("L");
    }
    
    return 0;
}

